<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script type="module">
      // 基本应用
      const data = {
        name: '张三',
        age: 20,
        info: {
          address: '福州' // 需要深度监听
        },
        nums: [10, 20, 30]
      }
      const reactive = (target = {}) => {
        if (typeof target !== 'object' || target == null) {
          return target
        }
        const proxyConf = {
          get(target, key, receiver) {
            // receiver实际是proxyData，继承Prxoy的对象
            // 非原型的属性才进行处理
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
              // 在这里加自己的处理
            }
            const result = Reflect.get(target, key, receiver)
            console.log('proxyConf get - ', target, key, receiver)
            return reactive(result)
          },
          set(target, key, val, receiver) {
            // 重复数据不处理
            const oldVal = target[key]
            if (val === oldVal) return true
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
              // 在这里加自己的处理
              // 进入到这里是已经有的key
            } else {
              // 进入到这里是新增的key
            }
            const result = Reflect.set(target, key, val, receiver)
            console.log('proxyConf set - ', target, key, val, receiver)
            return result
          },
          deleteProperty(target, key) {
            const result = Reflect.deleteProperty(target, key)
            return result
          }
        }
        const observed = new Proxy(target, proxyConf)
        return observed
      }

      window.reactive = reactive
      const newData = reactive(data)

      newData.name = '李四'
      newData.age = 21
      newData.x = '100'
      delete newData.name
      newData.info.address = '福建'
      newData.nums.push(40)
    </script>
  </head>
  <body></body>
</html>
